﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Proggy.Web.Cms.PropertyTypes;
using System.ComponentModel.DataAnnotations;

namespace Proggy.Web.Cms.ContentModel
{
    /// <summary>
    /// When a property is decorated with this attribute, it will "self set"
    /// </summary>
    [AttributeUsage(AttributeTargets.Property)]
    public class ContentModelPropertyTypeAttribute : ValidationAttribute
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tabName">The tab on which the property should appear</param>
        /// <param name="friendlyName">The friendly name to display in the editor</param>
        /// <param name="propertyName">MANDATORY - the name of the property it is decorating, case-sensitive</param>        
        public ContentModelPropertyTypeAttribute(
            string tabName,
            string friendlyName,
            string propertyName)
        {
            this.TabName = tabName;
            this.FriendlyName = friendlyName;
            this.PropertyName = propertyName;
            //this.HasConfigObject = hasConfigObject;
            //if (hasConfigObject)
            //{
            //    this.ConfigObjectPropertyName = configObjectPropertyName;                
            //}
        }

        /// <summary>
        /// The display name for the property
        /// </summary>
        public string FriendlyName { get; private set; }

        /// <summary>
        /// The tab name in which this resides
        /// </summary>
        public string TabName { get; private set; }

        /// <summary>
        /// The name of the property this is decorating
        /// </summary>
        public string PropertyName { get; private set; }

        ///// <summary>
        ///// If true, has config object
        ///// </summary>
        //public bool HasConfigObject { get; set; }

        ///// <summary>
        ///// Optional
        ///// </summary>
        //public string ConfigObjectPropertyName { get; set; }

        ///// <summary>
        ///// The arguments
        ///// </summary>
        //public object[] Args { get; set; }

        /// <summary>
        /// Override is valid
        /// </summary>
        /// <param name="value"></param>
        /// <param name="validationContext"></param>
        /// <returns></returns>
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            // check value
            if (value == null) { 
                // get prop
                var prop = validationContext.ObjectType.GetProperties().Single(x => x.Name == this.PropertyName);

                // set value
                value = Activator.CreateInstance(prop.PropertyType);
            }

            // get validation
            var validation = this.isValid(value, validationContext);

            // if ok, return nothing
            if (validation.Item1)
            {
                return null;
            }

            // get prop name
            var propName = this.ErrorMessageResourceName;

            // not ok, so return error messaged v result
            return new ValidationResult("<span class=\"proggy-custom-data-message\" data-tab=\"" + this.TabName + "\" />" + validation.Item2);
        }

        /// <summary>
        /// Private function for is valid
        /// </summary>
        /// <param name="value"></param>
        /// <param name="vContext"></param>
        /// <returns></returns>
        private Tuple<bool, string> isValid(object value, ValidationContext vContext)
        {
            //// check
            //if (value == null)
            //{
            //    return new Tuple<bool, string>(true, "");
            //}

            // get validation context type
            var instance = (IValidatablePropertyType)value;

            // 
            return instance.GetIsValid(vContext, this);
        }
    }
}
